package com.yangtao.framework.mapping.impl;

import com.yangtao.framework.mapping.Mapper;
import com.yangtao.framework.mapping.config.MappingConfig;
import com.yangtao.framework.mapping.config.PropertyConfig;
import com.yangtao.framework.util.DataType;
import com.yangtao.framework.util.ReflectionUtils;
import org.springframework.util.Assert;

import java.util.Map;

/**
 * @auther: 杨涛
 * Date: 11-4-20
 * Time: 下午5:30
 * @version: 1.0
 */
public class MapperImpl implements Mapper {

	private Map<String, MappingConfig> configMap;

	/**
	 * 从源对象复制属性到目标对象
	 *
	 * @param orig 源对象
	 * @param dest 目标对象
	 */
	public void map(Object orig, Object dest) {
		if (orig == null || dest == null) {
			return;
		}
		String mappingId = orig.getClass().getName() + dest.getClass().getName();
		map(orig, dest, mappingId);
	}

	/**
	 * 从源对象复制属性到目标对象
	 *
	 * @param orig      源对象
	 * @param dest      目标对象
	 * @param mappingId 映射文件Id
	 */
	public void map(Object orig, Object dest, String mappingId) {
		Assert.hasText(mappingId, "mappingId can't be null");
		MappingConfig mappingConfig = configMap.get(mappingId);
		Assert.notNull(mappingConfig, "mappingConfig can't be null");
		for (PropertyConfig propertyCfg : mappingConfig.getActualPropertyMappingList()) {
			String destPropertyName = propertyCfg.getDestPropertyName();
			String srcPropertyName = propertyCfg.getSrcPropertyName();
			int srcPropertyType = propertyCfg.getSrcPropertyType();
			int destProertyType = propertyCfg.getDestPropertyType();
			//首先判断是不是简单类型
			if (DataType.isSimpleType(srcPropertyType) && DataType.isSimpleType(destProertyType)) {
				Object propeValue = ReflectionUtils.getProperty(orig, srcPropertyName);
				//如果是相同类型，直接赋值
				if (isSameType(srcPropertyType, destProertyType)) {
					ReflectionUtils.setProperty(dest, destPropertyName, propeValue);
				}
				//如果不是相同类型，进行类型装换
				else {
					//TODO 1 根据类型，选择类型转换器
					//TODO 2 使用类型转换器，进行类型转换
				}
			}
			//TODO 如果不是简单类型，目前暂时不考虑
			else {

			}
		}
	}

	/**
	 * 判断两个类型是否相同
	 *
	 * @param srcType
	 * @param destType
	 * @return
	 */
	protected boolean isSameType(Object srcType, Object destType) {
		if (srcType == destType)
			return true;
		return false;
	}

	public Map<String, MappingConfig> getConfigMap() {
		return configMap;
	}

	public void setConfigMap(Map<String, MappingConfig> configMap) {
		this.configMap = configMap;
	}
}
